require.config({
    paths: {
        'axios': 'axios-0.19.0.min'
    }
})

require(['core', 'template-web', 'layer', 'printer', 'axios', 'drawer'], function (c, tpl, layer, printer, axios, drawer) {
    // 获取字体名映射表
    var fontMapping = {
        "微软雅黑": "Microsoft Yahei",
        "宋体": "SimSun",
        "黑体": "SimHei",
        "楷体": "KaiTi",
        "仿宋": "FangSong"
    }
    var fontReverseMapping = {}
    function getFontName(cnName) {
        var name = fontMapping[cnName] || cnName
        return name.replace(/\"/g, '')
    }
    function getFontNameCn(enName) {
        return fontReverseMapping[enName] || enName
    }

    // init drawer
    drawer.init('.actions a', 'print')

    var form = c.one('#design-zone form')
    var defaults = {
        fontName: getFontName('微软雅黑'),
        fontSize: 11, // pt
        imageSrc: 'images/image.png'
    }

    // export global function
    window.getLabelItems = function () {
        var items = c.all('#design-zone form .label-item')
        var info = []
        c.each(items, function (item) {
            var x = parseInt(item.style.left)
            var y = parseInt(item.style.top)
            var width = parseInt(item.style.width) || 200
            var height = parseInt(item.style.height) || 24
            var type = c.data(item, 'type')
            var detail = {
                x: x,
                y: y,
                width: width,
                height: height,
                type: type,
            }
            switch (type) {
                case 'text':
                case 'code':
                    // printer.addPrintText(x, y, width, height, item.value || '未设置打印内容')
                    var fontName = getFontName(item.style.fontFamily)
                    var fontSize = parseInt(item.style.fontSize) || 11
                    // printer.setPrintFontName(index + offset, fontName)
                    // printer.setPrintFontSize(index + offset, fontSize)
                    detail.fontName = fontName
                    detail.fontSize = fontSize
                    break
                case 'barcode':
                    break;
                case 'image':
                case 'ccc':
                case 'qrcode':
                    // printer.addPrintImage(x, y, width, height, item.src)
                    detail.imageSrc = item.src
                    break
            }
            info.push(detail)
        })
        return info
    }

    // fix javafx webview drageend pageX is always 0
    var dragEndPos = { x: 0, y: 0 }
    if (navigator.userAgent.indexOf('JavaFX/') >= 0) {
        form.addEventListener('dragover', function (evt) {
            dragEndPos.x = evt.pageX
            dragEndPos.y = evt.pageY
        }, false)
    }
    c.each(c.all('.control-item'), function (item) {
        item.addEventListener('dragstart', function (evt) {
            c.log('start: ' + evt.pageX + ', ' + evt.pageY)
        })
        // item.addEventListener('drag', function (evt) {
        // c.log('drag: ' + evt.pageX + ', ' + evt.pageY)
        // c.moveTo(proxy, { x: evt.pageX - 24, y: evt.pageY - 24 })
        // })
        item.addEventListener('dragend', function (evt) {
            // c.log('end: ' + evt.pageX + ', ' + evt.pageY)
            var type = c.data(item, 'type')
            var id = c.nextName(type + '-')
            var x = (evt.pageX || dragEndPos.x) - 72
            var y = (evt.pageY || dragEndPos.y) - 60
            var newItem
            switch (type) {
                case 'text':
                    newItem = addText(id, x, y, defaults)
                    break;
                case 'code':
                    newItem = addCode(id, x, y, defaults)
                    break;
                case 'barcode':
                    newItem = addBarcode(id, x, y)
                    break;
                case 'image':
                    var src = c.attr(evt.target, 'src')
                    newItem = addImage(id, x, y, { imageSrc: src.replace(/icon-/g, '') })
                    break;
                case 'line':
                    y += 16
                    newItem = addLine(id, x, y)
                    break
            }
            if (newItem) {
                c.data(newItem, 'type', type)
                form.appendChild(newItem)
                updateProps(newItem)
                newItem.addEventListener('click', function () {
                    updateProps(newItem)
                })
            }
        })
    })

    function addText(id, x, y, options, width, height) {
        var w = width || 200
        var h = height || 24
        options.width = w
        options.height = h

        var el = document.createElement('div')
        el.id = id
        el.value = id
        el.style.position = 'absolute'
        el.style.width = w + 'px'
        el.style.height = h + 'px'
        c.attr(el, 'readonly', 'readonly')
        c.attr(el, 'class', 'label-item')
        c.attr(el, 'tabindex', '0') // enable :focus style
        text2image(el, options)
        c.moveTo(el, { x: x, y: y })
        return el
    }

    function text2image(el, options) {
        var text = options.value || ''
        var w = options.width || 200
        var h = options.height || 24
        var fontName = options.fontName || '微软雅黑'
        var fontSize = options.fontSize || 11
        var bold = options.fontBold || false
        c.data(el, 'options', JSON.stringify(options))
        var url = 'api/text-to-image?t=' + Date.now().toString(36) +
            '&text=' + text + '&width=' + w + '&height=' + h +
            '&fontFamily=' + fontName + '&fontSize=' + fontSize + '&bold=' + bold
        el.style.backgroundImage = 'url("' + url + '")'
    }

    function addCode(id, x, y, options, width, height) {
        return addText(id, x, y, options, width, height)
    }

    function addBarcode(id, x, y, width, height) {
        var el = document.createElement('div')
        el.id = id
        el.tabIndex = 0
        el.value = '12345678901'
        el.style.position = 'absolute'
        el.style.width = (width || 140) + 'px'
        el.style.height = (height || 60) + 'px'
        c.attr(el, 'class', 'label-item label-barcode')
        c.moveTo(el, { x: x, y: y })
        return el
    }

    function addImage(id, x, y, options, width, height) {
        var el = document.createElement('img')
        el.id = id
        el.tabIndex = 0
        el.value = id
        el.style.position = 'absolute'
        el.style.width = (width || 64) + 'px'
        el.style.height = (height || 64) + 'px'
        c.attr(el, 'class', 'label-item')
        c.attr(el, 'src', options.imageSrc)
        c.moveTo(el, { x: x, y: y })
        return el
    }

    function addQrcode(id, x, y, width, height) {
        return addImage(id, x, y, { imageSrc: 'images/qrcode.png' }, width, height)
    }

    function addLine(id, x, y, width, height) {
        var el = document.createElement('div')
        el.id = id
        el.tabIndex = 0
        el.value = id
        el.style.position = 'absolute'
        el.style.width = (width || 200) + 'px'
        el.style.height = (height || 2) + 'px'
        c.attr(el, 'class', 'label-item label-line')
        c.moveTo(el, { x: x, y: y })
        return el
    }

    var props = c.one('.properties form')
    function updateProps(cmp) {
        var options = c.data(cmp, 'options') || {}
        var values = {
            'id': cmp.id,
            'value': options.value || '',
            'left': parseInt(cmp.style.left),
            'top': parseInt(cmp.style.top),
            'width': parseInt(cmp.style.width),
            'height': parseInt(cmp.style.height)
        }
        var type = c.data(cmp, 'type')
        if (type == 'text' || type == 'code') {
            var fontName = getFontName(options.fontName)
            var fontSize = parseInt(options.fontSize)
            values.fontName = getFontNameCn(fontName)
            values.fontSize = fontSize
            values.fontBold = options.fontBold
        }
        c.setFormValues(props, values)
    }

    var actions = {
        preview: function () {
            var items = c.all('#design-zone form .label-item')
            if (!items.length) {
                layer.open({ content: '请先在设计区域(虚线框内)添加要打印的内容！', btn: '好的' })
                return
            }
            layer.open({
                type: 1,
                content: '<img src="/api/design-preview">',
                anim: 'up',
                style: 'border-radius: 4px;',
                btn: ['关闭'],
                yes: function (index) {
                    layer.close(index);
                }
            })
        },
        saveLabel: function () {
            var items = c.all('#design-zone form .label-item')
            if (!items.length) {
                layer.open({ content: '请先在设计区域(虚线框内)添加要打印的内容！', btn: '好的' })
                return
            }
            var labelItems = []
            c.each(items, function (item) {
                var options = c.data(item, 'options') || {}
                var values = {
                    id: item.id,
                    value: options.value || '',
                    type: c.data(item, 'type'),
                    left: parseInt(item.style.left),
                    top: parseInt(item.style.top),
                    width: parseInt(item.style.width) || 200,
                    height: parseInt(item.style.height) || 24,
                }
                var type = c.data(item, 'type')
                if (type == 'text' || type == 'code') {
                    var fontName = getFontName(options.fontName) || defaults.fontName
                    var fontSize = parseInt(options.fontSize || defaults.fontSize)
                    values.fontName = fontName
                    values.fontSize = fontSize
                    values.fontBold = options.fontBold
                } else if (type == 'image' || type == 'ccc' || type == 'qrcode') {
                    values.imageSrc = c.attr(item, 'src') || defaults.imageSrc
                }
                labelItems.push(values)
            })
            axios.post('/api/label', { name: '默认格式', items: labelItems })
                .then(function (resp) {
                    if (resp.data && resp.data.success) {
                        layer.open({
                            content: '保存成功！', btn: '好的', yes: function () {
                                location.reload()
                            }
                        })
                    } else {
                        updateProps({})
                    }
                })
                .catch(function (err) {
                    layer.open({ content: err, btn: '好的' })
                    updateProps({})
                })
        },
        gotoPrint: function () {
            // layer.open({ content: '暂未实现！', btn: '好的' })
            c.doc.location.href = 'print.html'
        },
        scaleSize: function () {
            var values = c.getFormValues(props)
            if (!values.id) return
            var cmp = c.one('#' + values.id)
            var width = parseInt(cmp.style.width) || 1
            var height = parseInt(cmp.style.height) || 1
            var ratio = height / width
            var newWidth = 1 * values.width;
            var newHeight = parseInt(newWidth * ratio)
            values.height = newHeight
            c.setFormValues(props, values)
            actions.updateDesign()
        },
        updateDesign: function () {
            var values = c.getFormValues(props)
            if (!values.id) return
            var cmp = c.one('#' + values.id)
            if (cmp) {
                cmp.value = values.value
                cmp.style.left = 1 * values.left + 'px'
                cmp.style.top = 1 * values.top + 'px'
                cmp.style.width = 1 * values.width + 'px'
                cmp.style.height = 1 * values.height + 'px'
                //                cmp.style.fontWeight = 700 // 设计时只有微软雅黑加粗有效果，打印时，所有字体都可加粗
            }
            var type = c.data(cmp, 'type')
            if (type == 'text' || type == 'code') {
                // var fontName = values.fontName || defaults.fontName
                // var fontSize = values.fontSize || defaults.fontSize
                // cmp.style.fontFamily = getFontName(fontName)
                // cmp.style.fontSize = (1 * fontSize) + 'pt'
                // cmp.style.fontWeight = ''
                // if (values.fontBold == 'true') {
                //     cmp.style.fontWeight = 'bold'
                // }
                text2image(cmp, values)
            }
        },
        deleteItem: function () {
            var values = c.getFormValues(props)
            if (!values.id) return
            var cmp = c.one('#' + values.id)
            if (cmp) {
                cmp.parentElement.removeChild(cmp)
                c.setFormValues(props, {
                    'id': '',
                    'value': '',
                    'left': '',
                    'top': '',
                    'width': '',
                    'height': ''
                })
            }
        }
    }
    c.each(c.all('.btns button'), function (btn) {
        btn.addEventListener('click', function () {
            var fn = actions[c.data(btn, 'action')]
            if (fn) fn(btn)
        })
    })

    layer.open({ type: 2, content: '加载默认标签格式' })
    axios.get('font.json').then(function (resp) {
        for (var key in resp.data) {
            var value = resp.data[key]
            fontMapping[key] = value
            fontReverseMapping[value] = key
        }
    })
    axios.get('/api/label/default-format.json').then(function (resp) {
        if (resp.data) {
            c.each(resp.data.items, function (item, index) {
                var id = item.id
                var x = item.left
                var y = item.top
                var width = item.width
                var height = item.height
                var newItem
                switch (item.type) {
                    case 'text':
                    case 'code':
                        newItem = addText(id, x, y, item, width, height)
                        break
                    case 'barcode':
                        newItem = addBarcode(id, x, y, width, height)
                        break
                    case 'ccc':
                    case 'image':
                        newItem = addImage(id, x, y, { imageSrc: item.imageSrc }, width, height)
                        break
                    case 'qrcode':
                        newItem = addQrcode(id, x, y, width, height)
                        break
                    case 'line':
                        y += 16
                        newItem = addLine(id, x, y, width, height)
                        break
                }
                if (newItem) {
                    c.data(newItem, 'type', item.type)
                    // newItem.value = item.value
                    form.appendChild(newItem)
                    // if (index + 1 == resp.data.items.length) updateProps(newItem)
                    newItem.addEventListener('click', function () {
                        updateProps(newItem)
                    })
                }
            })
        }
        setTimeout(layer.closeAll, 1000)
        return axios.get('/api/font/font-list')
    }).then(function (resp2) {
        if (resp2.data) {
            var html = tpl('font-names-tpl', {
                items: resp2.data
            })
            c.one('.properties select[name="fontName"]').innerHTML = html
        }
    }).catch(function (err) {
        layer.closeAll()
        layer.open({ content: err || '加载默认标签失败！', btn: '好的' })
    })

    // handle keyboard event
    form.onkeyup = function (evt) {
        var el = evt.target
        if (el.className == 'label-item' && evt.keyCode == 46) { // 46: delete
            actions.deleteItem()
        }
    }

    props.onkeyup = function (evt) {
        var el = evt.target
        if (evt.keyCode == 13 && c.attr(el, 'name') && !c.attr(el, 'readonly')) {
            actions.updateDesign()
        }
    }
})
